﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using Eneta.Portal.Common;
using Eneta.Portal.Common.Dto;
using Eneta.Portal.Common.Helpers;
using Eneta.Portal.Common.Repository;
using Microsoft.SharePoint;
using System.Web;

namespace Eneta.Portal.NewsAndBlogs.Controls
{
    public class BlogPostControl : UserControl
    {
        protected HtmlAnchor blogNameLink;
        protected HtmlGenericControl blogNameInLink;

        protected HtmlAnchor profileLink;
        protected HtmlImage profileImage;
        protected HtmlAnchor authorLink;
        protected HtmlGenericControl publishDate;
        protected HtmlAnchor titleLink;
        protected HtmlGenericControl summaryField;
        protected HtmlAnchor readMoreLink;
        protected HtmlGenericControl promoBox;
        protected PlaceHolder profilenav;
        protected PlaceHolder AddButtons;

        protected HtmlGenericControl ReadOnlyKeywordsContainer;
        protected Repeater ReadOnlyKeywordsRepeater;

        protected Label StatusLabel;
        protected HtmlGenericControl AcceptPostingContainer;
        protected Repeater keywordGroupsRepeater;
        protected Button AcceptEntry;
        protected Button RejectEntry;

        protected HtmlGenericControl CommentsCount;
        protected Repeater CommentsRepeater;
        protected HtmlGenericControl AddCommentContainer;
        protected HtmlAnchor AddCommentProfileLink;
        protected HtmlImage AddCommentProfileImage;
        protected HtmlAnchor AddCommentProfileNameLink;

        protected TextBox CommentField;
        protected Button SubmitComment;

        protected HtmlAnchor footerBlogLink;
        protected HtmlImage footerProfileImage;
        protected HtmlGenericControl footerBlogName;

        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);

            ReadOnlyKeywordsRepeater.ItemDataBound += ReadOnlyKeywordsRepeaterItemDataBound;
            CommentsRepeater.ItemDataBound += CommentsRepeaterItemDataBound;
            SubmitComment.Click += SubmitCommentClick;
            AcceptEntry.Click += AcceptEntryClick;
            RejectEntry.Click += RejectEntryClick;
            keywordGroupsRepeater.ItemDataBound += KeywordGroupsRepeaterItemDataBound;

        }

        void KeywordGroupsRepeaterItemDataBound(object sender, RepeaterItemEventArgs e)
        {
            if (e.Item.DataItem == null)
                return;

            var groupName = (string)e.Item.DataItem;

            var groupNameLabel = (Label)e.Item.FindControl("groupNameLabel");
            groupNameLabel.Text = groupName;

            var keywordCheckList = (CheckBoxList)e.Item.FindControl("KeywordCheckList");

            var query = from k in GetAllKeywords()
                        where k.GroupName == groupName
                        orderby k.Title
                        select k;
            keywordCheckList.DataSource = query;
            keywordCheckList.DataBind();

            foreach (ListItem item in keywordCheckList.Items)
            {
                var keywordId = int.Parse(item.Value);
                item.Selected = Post.Keywords.Exists(p => p.Id == keywordId);
            }
        }

        protected void ReadOnlyKeywordsRepeaterItemDataBound(object sender, RepeaterItemEventArgs e)
        {
            if (e.Item.DataItem == null)
                return;

            var keyword = (KeywordDto)e.Item.DataItem;
            var keywordLink = (HtmlGenericControl)e.Item.FindControl("KeywordLink");
            keywordLink.InnerText = keyword.Title;
        }

        protected void RejectEntryClick(object sender, EventArgs e)
        {
            AcceptItem(false);
            Response.Redirect(Request.RawUrl, false);
        }

        protected void AcceptEntryClick(object sender, EventArgs e)
        {
            AcceptItem(true);
            Response.Redirect(Request.RawUrl, false);
        }

        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            var user = SPContext.Current.Web.CurrentUser;

            if (Post == null)
            {
                if (user != null)
                    if (user.IsSiteAdmin)
                        return;
 
                Response.Redirect("/uudised/blogid/");
                return;
            }

            if (IsPostBack)
                return;

            var title = "Blogid > " + Post.BlogName + " > " + Post.Title + " | Microsoft Eneta";
            HttpContext.Current.Items["PageTitle"] = title;   

            blogNameLink.HRef = "/uudised/blogid/Lehed/" + Post.BlogUrl;
            blogNameInLink.InnerText = Post.BlogName;

            var profileRepository = new UserProfileRepository(SPContext.Current.Web);
            var profile = profileRepository.GetUserProfileById(Post.AuhtorId);

            profileLink.HRef = "/profile.aspx?ID=" + Post.ProfileId;
            profileImage.Src = profile.UserImage32x32Url; // "/_layouts/enetahandlers/userimagehandler.ashx?size=32&id=" + Post.ProfileId;
            authorLink.HRef = profileLink.HRef;
            authorLink.InnerText = Post.Author;
            publishDate.InnerText = Post.Date.ToString("dd.MM.yyyy");
            titleLink.HRef = Post.Url;
            titleLink.InnerText = Post.Title;
            summaryField.InnerHtml = RegExHelper.DetectAndReplaceUrls(Post.Summary);
            readMoreLink.HRef = Post.Url;

            footerBlogLink.HRef = blogNameLink.HRef;
            footerBlogName.InnerText = Post.BlogName;
            footerProfileImage.Src = profileImage.Src;

            CommentsCount.InnerText = Post.Comments.Count.ToString();
            try
            {
                CommentsRepeater.DataSource = Post.Comments;
                CommentsRepeater.DataBind();
            }
            catch (Exception ex)
            {
                Logger.LogWarning("OnLoad(): Error loading page", GetType().ToString());
                Logger.LogException(ex);
            }

            AcceptPostingContainer.Visible = false;
            var currentUser = SPContext.Current.Web.CurrentUser;

            ReadOnlyKeywordsContainer.Visible = false;
            if (currentUser != null && currentUser.IsSiteAdmin)
            {
                AcceptPostingContainer.Visible = true;
                var query = from k in GetAllKeywords()
                            orderby k.GroupName
                            select k.GroupName;
                if (query.Count() > 0)
                {
                    keywordGroupsRepeater.DataSource = query.Distinct();
                    keywordGroupsRepeater.DataBind();
                }
                if (Post.Status == SPModerationStatusType.Approved)
                    StatusLabel.Text = Resources.NewsAndBlogs.Approved;
                else if (Post.Status == SPModerationStatusType.Denied)
                    StatusLabel.Text = Resources.NewsAndBlogs.Denied;
                else
                    StatusLabel.Text = Resources.NewsAndBlogs.Pending;
            }
            else
            {
                ReadOnlyKeywordsContainer.Visible = true;
                foreach (var plah in Post.Keywords)
                    Logger.LogInfo("KEY: " + plah.Title, GetType().ToString());
                ReadOnlyKeywordsRepeater.DataSource = Post.Keywords;
                ReadOnlyKeywordsRepeater.DataBind();
            }

            if (currentUser == null)
            {
                AddCommentContainer.Visible = false;
                if (profilenav != null)
                    profilenav.Visible = true;
                return;
            }

            var profileRep = new UserProfileRepository(SPContext.Current.Web);
            var profileItem = profileRep.GetUserProfileByUserName(currentUser.LoginName);

            if (profileItem == null)
            {
                AddCommentContainer.Visible = false;
                return;
            }

            if (SPContext.Current.Web.CurrentUser != null)
            {
                if (AddButtons != null)
                    AddButtons.Visible = true;
            }


            AddCommentProfileLink.HRef = "/profile.aspx?ID=" + profileItem.Id;
            AddCommentProfileLink.Title = currentUser.Name;
            AddCommentProfileImage.Src = profileItem.UserImage32x32Url; //profile.UserImage32x32Url; // "/_layouts/enetahandlers/userimagehandler.ashx?size=32&id=" + profileItem.ID;
            AddCommentProfileImage.Alt = currentUser.Name;
            AddCommentProfileNameLink.HRef = AddCommentProfileLink.HRef;
            AddCommentProfileNameLink.Title = AddCommentProfileLink.Title;
            AddCommentProfileNameLink.InnerText = AddCommentProfileLink.Title;
            string promoText =
                    "<p>{0} <a href='/uudised/teated/AddAnnouncement.aspx'>kirjuta uudis</a> või <a href='/addblog.aspx'>lisa oma blogi</a>.</p>";
            promoText = string.Format(promoText, profileItem.UserName);
            if (promoBox != null)
                promoBox.InnerHtml = promoText;
            else
                Logger.LogWarning("OnLoad(): Cannot find control promoBox", GetType().ToString());
        }
        
        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);
                     
        }

        private BlogEntryDto _post;

        protected BlogEntryDto Post
        {
            get
            {
                if (_post != null)
                    return _post;

                var repository = new BlogRepository(SPContext.Current.Web);
                var id = SPContext.Current.ItemId;
                _post = repository.GetBlogEntryById(id);
                return _post;
            }
        }

        protected void CommentsRepeaterItemDataBound(object sender, RepeaterItemEventArgs e)
        {
            if (e.Item.DataItem == null)
                return;

            var comment = (CommentDto)e.Item.DataItem;
            var commentProfileLink = (HtmlAnchor)e.Item.FindControl("CommentProfileLink");
            var commentProfileImage = (HtmlImage)e.Item.FindControl("CommentProfileImage");
            var commentBody = (HtmlGenericControl)e.Item.FindControl("CommentBody");
            var commentProfileNameLink = (HtmlAnchor)e.Item.FindControl("CommentProfileNameLink");
            var commentTime = (HtmlGenericControl)e.Item.FindControl("CommentTime");

            var profileRepository = new UserProfileRepository(SPContext.Current.Web);
            var profile = profileRepository.GetUserProfileById(comment.OwnerProfileId);

            commentProfileLink.HRef = "/profile.aspx?ID=" + comment.OwnerProfileId;
            commentProfileLink.Title = comment.OwnerName;
            commentProfileImage.Src = profile.UserImage32x32Url; // "/_layouts/enetahandlers/userimagehandler.ashx?size=32&id=" + comment.OwnerProfileId;
            commentProfileImage.Alt = comment.OwnerName;

            commentBody.InnerHtml = RegExHelper.DetectAndReplaceUrls(comment.Body.Replace("\n", "<br/>"));
            commentProfileNameLink.HRef = commentProfileLink.HRef;
            commentProfileNameLink.Title = commentProfileLink.Title;
            commentProfileNameLink.InnerText = commentProfileLink.Title;
            commentTime.InnerText = comment.Created.ToString();
        }

        protected void SubmitCommentClick(object sender, EventArgs e)
        {
            var siteId = SPContext.Current.Site.ID;
            var userName = SPContext.Current.Web.CurrentUser.LoginName;

            var sec = new SPSecurity.CodeToRunElevated(delegate
            {
                using (var site = new SPSite(siteId))
                {
                    using (var web = site.OpenWeb("/uudised/blogid/"))
                    {
                        var list = web.Lists["FeedEntriesComments"];
                        var item = list.Items.Add();
                        item["Comment"] = CommentField.Text;

                        var authorFieldId = item.Fields.GetFieldByInternalName("Author").Id;
                        item[authorFieldId] = web.SiteUsers[userName];

                        var feedEntryValue = new SPFieldLookupValue(Post.ID, Post.Title);
                        item["FeedEntry"] = feedEntryValue;

                        item.Update();
                        list.Update();
                    }
                }
            });
            SPSecurity.RunWithElevatedPrivileges(sec);
            Response.Redirect(Request.RawUrl, true);
        }

        private List<KeywordDto> _allKeywords;
        private List<KeywordDto> GetAllKeywords()
        {
            if (_allKeywords != null)
                return _allKeywords;

            var keywords = new List<KeywordDto>();
            var siteId = SPContext.Current.Site.ID;

            var sec = new SPSecurity.CodeToRunElevated(delegate
            {
                using (var site = new SPSite(siteId))
                {
                    using (var web = site.OpenWeb())
                    {
                        var list = web.Lists["Keywords"];
                        var items = list.Items;

                        if (items == null)
                            return;
                        if (items.Count < 1)
                            return;


                        foreach (SPListItem item in items)
                        {
                            var lookup = new KeywordDto();
                            lookup.Id = item.ID;
                            lookup.Title = item.Title;
                            if (item["KeywordGroup"] != null)
                                lookup.GroupName = item["KeywordGroup"].ToString();
                            keywords.Add(lookup);
                        }
                    }
                }
            });
            SPSecurity.RunWithElevatedPrivileges(sec);

            _allKeywords = keywords;
            return _allKeywords;
        }

        private void AcceptItem(bool accept)
        {
            var siteId = SPContext.Current.Site.ID;
            
            using (var site = new SPSite(siteId))
            {
                using (var web = site.OpenWeb("/uudised/blogid/"))
                {
                    var list = web.Lists["Lehed"];
                    SPListItem item;
                    try
                    {
                        item = list.GetItemById(Post.ID);
                    }
                    catch (Exception ex)
                    {
                        Logger.LogInfo("Cannot get feed entry with ID " + Post.ID, GetType().ToString());
                        Logger.LogException(ex);
                        throw;
                    }

                    var dto = new AdminActivityDto();
                    dto.PreviousEditor = new SPFieldUserValue(web, item["Editor"].ToString()).User.LoginName;
                    dto.PreviousStatus = item.ModerationInformation.Status;
                    dto.PreviousTimeStamp = (DateTime)item["Modified"];
                    dto.Module = "BlogEntries";
                    dto.Url = "/uudised/blogid/Lehed/" + item["FileLeafRef"];

                    //item["Accepted"] = accept;
                    item.File.CheckOut();
                    if (accept)
                    {
                        var keywords = new SPFieldLookupValueCollection();

                        foreach (RepeaterItem groupItem in keywordGroupsRepeater.Items)
                        {
                            var checkList = (CheckBoxList)groupItem.FindControl("KeywordCheckList");
                            if (checkList == null)
                            {
                                Logger.LogWarning("AcceptItem(): Cannot find KeywordCheckList", GetType().ToString());
                                continue;
                            }
                            foreach (ListItem checkItem in checkList.Items)
                            {
                                if (!checkItem.Selected)
                                    continue;
                                var id = int.Parse(checkItem.Value);
                                var text = checkItem.Text;
                                var keyword = new SPFieldLookupValue(id, text);
                                keywords.Add(keyword);
                            }
                        }
                        Logger.LogInfo("AcceptItem(): keywords: " + keywords.Count, GetType().ToString());
                        item["Keywords"] = keywords;
                    }
                    item.Update();
                    item = list.GetItemById(Post.ID);
                    item.File.CheckIn(string.Empty, SPCheckinType.MajorCheckIn);
                    //if (item.ModerationInformation != null)
                    //{
                        if (accept)
                            item.File.Approve(string.Empty); //item.ModerationInformation.Status = SPModerationStatusType.Approved;
                        else
                            item.File.Deny(string.Empty); //item.ModerationInformation.Status = SPModerationStatusType.Denied;
                    //}
                    item = list.GetItemById(Post.ID);
                    //item.Update();

                    dto.CurrentEditor = new SPFieldUserValue(web, item["Editor"].ToString()).User.LoginName;
                    dto.CurrentStatus = item.ModerationInformation.Status;
                    dto.CurrentTimeStamp = (DateTime)item["Modified"];
                    ActivityLogger.LogActivity(dto);
                }
            }
        }
    }
}
